package managedbean.developer;

import util.enumeration.Country;
import exception.ExistException;
import java.io.Serializable;
import java.util.Date;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.ejb.EJB;
import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.RequestScoped;
import javax.faces.context.FacesContext;
import javax.faces.event.ActionEvent;
import managedbean.PageRedirectorBean;
import org.primefaces.model.MenuModel;
import session.stateless.SystemMessagesBean;
import session.stateless.StaffAccountSessionBean;
import util.entityhelper.StaffAccountState;
import util.enumeration.AccessRight;
import util.enumeration.Department;
import util.enumeration.Gender;
import util.enumeration.JobPosition;
import util.enumeration.UserRoleType;
import util.localization.WebLocalization;

/**
 *
 * @author Wen Yong
 */
@ManagedBean
@RequestScoped
public class StaffCreateSuperAdmin implements Serializable {
    @EJB
    private StaffAccountSessionBean staffAccountMgr;
    // display exception
    @EJB
    private SystemMessagesBean systemMessages;
    private FacesContext ctx = FacesContext.getCurrentInstance();
    
    // use entity helpers to extract data (attribute extraction and formatting instead of entity in this open bean)
    private StaffAccountState staffAcctState;
    private WebLocalization localization;
    private PageRedirectorBean redirect;
    
    // fields passed from session
    private Long staffAccountId;
    private String preferredLocale;
    
    // other fields from database
    private String username;
//    private String password;
//    private String confirmPassword;
    private String lastname;
    private String firstname;
    private String gender;
    private Date birthdate;
    private String country;
    private String locale;
    private String email;
    private String emailSecondary;
    private String department;
    private String jobPosition;
    private String userRoleType;
    private Date joinDate;
    private List<AccessRight> accessRightsList;
    
    private MenuModel staffMenuModel;
    

    public StaffCreateSuperAdmin() {
        /* LOCALIZATION */
        localization = new WebLocalization();
        preferredLocale = localization.getPreferredLocaleFromSession();
        /* END LOCALIZATION */
        
        redirect = new PageRedirectorBean();
        /* pre-load values from session and database */
        // get account ID values from session
     /*   if (ctx.getExternalContext().getSessionMap().containsKey("staffAccountId")) {
            // get session values
            staffAccountId = (Long) ctx.getExternalContext().getSessionMap().get("staffAccountId");
            // put back session values
            ctx.getExternalContext().getSessionMap().put("staffAccountId", staffAccountId);
        }*/
        // TODO: REMOVE WHEN DONE
//        else {
//            // redirect back to login
//            redirect.goStaffLoginPageAtPreviousLevel();
//        }
        /* END load values from session and database */    
    }
    
   /* public void initView(PhaseEvent event) {
        try {
//            // set language for all MANAGERS for all THROWABLE EXCEPTIONS in backend
//            // to use this line everytime possible language changes
//            staffAccountMgr.setSelectedLocale(preferredLocale);
//            // get data from backend, exception alrd thrown by backend if these methods fail.
//            
//            staffAcctState = staffAccountMgr.getStaffAccountByID(staffAccountId);
            
//            // menu
//            StaffMenuGenerator menuGenerator = new StaffMenuGenerator(staffAcctState);
//            staffMenuModel = menuGenerator.generateStaffMenu();
        }
//        catch (ExistException ex) {
////            System.out.println(ex.getMessage());
//            FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, ex.getMessage(), ""));
//        }
        catch (Exception ex) {
            ex.printStackTrace();
//            FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, ex.getMessage(), ""));
        }
    }
    */
    public void registerStaff(ActionEvent event) {    
        try {   
            /* validations first */
            if (checkUsernameAvailability(username) == false) {
                // print error message
                String statusMessage = systemMessages.getSystemMessage("USERNAME_NOT_OK", preferredLocale);
                FacesContext.getCurrentInstance().addMessage(username, new FacesMessage(FacesMessage.SEVERITY_ERROR, statusMessage, ""));
            }
            else {
                // set language for all MANAGERS for all THROWABLE display exceptions in backend
                // to use this line everytime language changes
                staffAccountMgr.setSelectedLocale(preferredLocale);

                // reformat all other required fields
                Gender g = Gender.valueOf(gender);
                Country c = Country.valueOf(country);
                Department d = Department.valueOf(department);
                JobPosition jp = JobPosition.valueOf(jobPosition);
                UserRoleType us = UserRoleType.valueOf(userRoleType);
                
                // set empty string to email and emailSecondary
                if (email == null) {
                    email = "";
                }
                if (emailSecondary == null) {
                    emailSecondary = "";
                }
                
                // email = username
                // password is auto-generated by backend
                staffAccountMgr.createStaffAccount(username, lastname, firstname, g, birthdate, c, locale, email, emailSecondary, d, jp, us, joinDate, accessRightsList);

                // print success message
                String statusMessage = systemMessages.getSystemMessage("ACCOUNT_CREATION_SUCCESS", preferredLocale);
                FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, statusMessage, ""));
            
                reset();
            }
        } catch (ExistException ex) {
            // display exception
            FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, ex.getMessage(), ""));
        } catch (Exception ex) {
            // display exception tp user
            FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, ex.getMessage(), ""));
            // backend message for Tcube
            ex.printStackTrace();   
        }
    }
        
    private boolean validateEmailFormat(String emailInput) {
        Pattern p = Pattern.compile(".+@.+\\.[a-z]+");
        Matcher m = p.matcher(emailInput);
        boolean matchFound = m.matches();

        if (!matchFound) {
            // means error
            return false;
        }
        return true;
    }
    
//    public void checkUsernameAvailability(ActionEvent event) {
    private boolean checkUsernameAvailability(String username) {
        boolean isAvailable = false;
        
        try {
            // set language for all MANAGERS for all THROWABLE display exceptions in backend
            // to use this line everytime language changes
            staffAccountMgr.setSelectedLocale(preferredLocale);
            
            staffAcctState = null;
            try {
                staffAcctState = staffAccountMgr.getStaffAccountByUsername(username);
            } 
            catch (Exception ex) {
                // do nothing, just let the system catch any exception and continue to next part for catching of null
            }
            
            if (staffAcctState == null) {
                // print ok message
//                String statusMessage = systemMessages.getSystemMessage("USERNAME_OK", preferredLocale);
//                FacesContext.getCurrentInstance().addMessage(username, new FacesMessage(FacesMessage.SEVERITY_INFO, statusMessage, ""));
                isAvailable = true;
            } 
            else {
                
            }
        }
//        catch (ExistException ex) {
//            // display exception
//            FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, ex.getMessage(), ""));
//        }
        catch (Exception ex) {
            // display exception to user
            FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, ex.getMessage(), ""));
            // backend message for Tcube
            ex.printStackTrace();   
        }
        
        return isAvailable;
    }
    
    private void reset() {
        username = "";
        lastname = "";
        firstname = "";
        gender = "";
        birthdate = null;
        country = "";
        locale = "";
        email = "";
        emailSecondary = "";
        department = "";
        jobPosition = "";
        userRoleType="";
        joinDate = null;
        accessRightsList = null;
    }

    public StaffAccountSessionBean getStaffAccountMgr() {
        return staffAccountMgr;
    }

    public void setStaffAccountMgr(StaffAccountSessionBean staffAccountMgr) {
        this.staffAccountMgr = staffAccountMgr;
    }

    public Date getBirthdate() {
        return birthdate;
    }

    public void setBirthdate(Date birthdate) {
        this.birthdate = birthdate;
    }

    public FacesContext getCtx() {
        return ctx;
    }

    public void setCtx(FacesContext ctx) {
        this.ctx = ctx;
    }

    public String getCountry() {
        return country;
    }

    public void setCountry(String country) {
        this.country = country;
    }

    public String getFirstname() {
        return firstname;
    }

    public void setFirstname(String firstname) {
        this.firstname = firstname;
    }

    public String getGender() {
        return gender;
    }

    public void setGender(String gender) {
        this.gender = gender;
    }

    public String getLastname() {
        return lastname;
    }

    public void setLastname(String lastname) {
        this.lastname = lastname;
    }

    public SystemMessagesBean getSystemMessages() {
        return systemMessages;
    }

    public void setSystemMessages(SystemMessagesBean systemMessages) {
        this.systemMessages = systemMessages;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getLocale() {
        return locale;
    }

    public void setLocale(String locale) {
        this.locale = locale;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public String getEmailSecondary() {
        return emailSecondary;
    }

    public void setEmailSecondary(String emailSecondary) {
        this.emailSecondary = emailSecondary;
    }

    public String getPreferredLocale() {
        return preferredLocale;
    }

    public void setPreferredLocale(String preferredLocale) {
        this.preferredLocale = preferredLocale;
    }

    public WebLocalization getLocalization() {
        return localization;
    }

    public void setLocalization(WebLocalization localization) {
        this.localization = localization;
    }
    
    public String getDepartment() {
        return department;
    }

    public void setDepartment(String department) {
        this.department = department;
    }

    public String getJobPosition() {
        return jobPosition;
    }

    public void setJobPosition(String jobPosition) {
        this.jobPosition = jobPosition;
    }

    public Date getJoinDate() {
        return joinDate;
    }

    public void setJoinDate(Date joinDate) {
        this.joinDate = joinDate;
    }

    public StaffAccountState getStaffAcctState() {
        return staffAcctState;
    }

    public void setStaffAcctState(StaffAccountState staffAcctState) {
        this.staffAcctState = staffAcctState;
    }

    public List<AccessRight> getAccessRightsList() {
        return accessRightsList;
    }

    public void setAccessRightsList(List<AccessRight> accessRightsList) {
        this.accessRightsList = accessRightsList;
    }

    public PageRedirectorBean getRedirect() {
        return redirect;
    }

    public void setRedirect(PageRedirectorBean redirect) {
        this.redirect = redirect;
    }

    public Long getStaffAccountId() {
        return staffAccountId;
    }

    public void setStaffAccountId(Long staffAccountId) {
        this.staffAccountId = staffAccountId;
    }

    public MenuModel getStaffMenuModel() {
        return staffMenuModel;
    }

    public void setStaffMenuModel(MenuModel staffMenuModel) {
        this.staffMenuModel = staffMenuModel;
    }

    public String getUserRoleType() {
        return userRoleType;
    }

    public void setUserRoleType(String userRoleType) {
        this.userRoleType = userRoleType;
    }
}
